/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is Forte for Java, Community Edition. The Initial * Developer of the Original Code is Sun Microsystems, Inc. Portions * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved. */ package org.netbeans.editor.view; import java.awt.Dialog; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import java.awt.event.WindowEvent; import java.awt.event.WindowAdapter; import java.awt.event.KeyListener; import java.awt.event.KeyEvent; import java.awt.event.ItemListener; import java.awt.event.ItemEvent; import java.util.Map; import java.util.HashMap; import java.util.Collections; import javax.swing.SwingUtilities; import javax.swing.JButton; import javax.swing.Timer; import javax.swing.JComboBox; import javax.swing.text.JTextComponent; import javax.swing.text.BadLocationException; import org.netbeans.editor.Settings; import org.netbeans.editor.SettingsUtil; import org.netbeans.editor.FindSupport; import org.netbeans.editor.LocaleSupport; import org.netbeans.editor.GuardedException; import org.netbeans.editor.Utilities; /** * Support for displaying find and replace dialogs * * @author Miloslav Metelka * @version 1.00 */ public class FindDialogSupport implements ActionListener { protected FindPanel findPanel; protected JButton[] findButtons; protected Dialog findDialog; protected Timer incSearchTimer; private static final String MNEMONIC_SUFFIX = "-mnemonic"; // NOI18N /** Whether the currently visible dialog is for replace */ protected boolean replaceDialog; public FindDialogSupport() { int delay = SettingsUtil.getInteger(null, Settings.FIND_INC_SEARCH_DELAY, 200); incSearchTimer = new Timer(delay, this); incSearchTimer.setRepeats(false); } protected FindPanel getFindPanel() { if (findPanel == null) { findPanel = new FindPanel(); } return findPanel; } protected JButton[] getFindButtons() { if (findButtons == null) { findButtons = new JButton[] { new JButton(LocaleSupport.getString("find-button-find", "Find")), // NOI18N new JButton(LocaleSupport.getString("find-button-replace", "Replace")), // NOI18N new JButton(LocaleSupport.getString("find-button-replace-all", "Replace All")), // NOI18N new JButton(LocaleSupport.getString("find-button-cancel", "Cancel")) // NOI18N }; } return findButtons; } protected Dialog buildFindDialog() { JButton[] fb = getFindButtons(); Dialog d = DialogSupport.getDialogCreator().createFindDialog( getFindPanel(), fb, 0, fb.length - 1, this); String ls = LocaleSupport.getString("find-button-find" + MNEMONIC_SUFFIX); // NOI18N char mnemonic = (ls != null && ls.length() > 0) ? ls.charAt(0) : 'F'; fb[0].setMnemonic(mnemonic); ls = LocaleSupport.getString("find-button-replace" + MNEMONIC_SUFFIX); // NOI18N mnemonic = (ls != null && ls.length() > 0) ? ls.charAt(0) : 'R'; fb[1].setMnemonic(mnemonic); ls = LocaleSupport.getString("find-button-replace-all" + MNEMONIC_SUFFIX); // NOI18N mnemonic = (ls != null && ls.length() > 0) ? ls.charAt(0) : 'A'; fb[2].setMnemonic(mnemonic); d.addWindowListener( new WindowAdapter() { public void windowActivated(WindowEvent evt) { windowAct(evt, true); } public void windowDeactivated(WindowEvent evt) { windowAct(evt, false); } } ); return d; } protected Dialog getFindDialogImpl(boolean isReplace) { replaceDialog = isReplace; if (findDialog == null) { findDialog = buildFindDialog(); } if (isReplace) { findPanel.updateReplace(); } else { findPanel.updateFind(); } return findDialog; } public Dialog getFindDialog() { return getFindDialogImpl(false); } public Dialog getReplaceDialog() { return getFindDialogImpl(true); } protected void showFindDialogImpl(boolean isReplace) { getFindDialogImpl(isReplace); // make sure it's built JTextComponent c = Utilities.getLastActiveComponent(); if (c != null) { String selText = c.getSelectedText(); if (selText != null) { findPanel.updateFindWhat(selText); } } findDialog.setVisible(true); findDialog.requestFocus(); findPanel.updateFocus(); } public void showFindDialog() { showFindDialogImpl(false); } public void showReplaceDialog() { showFindDialogImpl(true); } public void actionPerformed(ActionEvent evt) { Object src = evt.getSource(); FindSupport fSup = FindSupport.getFindSupport(); if (src == findButtons[0]) { // Find button findPanel.updateFindHistory(); findPanel.save(); if (fSup.find(null, false)) { // found } if (!replaceDialog) { findDialog.setVisible(false); } } else if (src == findButtons[1]) { // Replace button findPanel.updateReplaceHistory(); try { findPanel.save(); if (fSup.replace(null, false)) { // replaced fSup.find(null, false); } } catch (GuardedException e) { // replace in guarded block } catch (BadLocationException e) { e.printStackTrace(); } } else if (src == findButtons[2]) { // Replace All button findPanel.updateReplaceHistory(); findPanel.save(); fSup.replaceAll(null); } else if (src == findButtons[3]) { // Cancel button findDialog.setVisible(false); /* !!! JTextComponent c = Utilities.getLastActiveComponent(); if (c != null) { ((BaseCaret)c.getCaret()).dispatchUpdate(); } */ } else if (src == incSearchTimer) { fSup.incSearch(findPanel.getFindProps()); } } protected void windowAct(WindowEvent evt, boolean activated) { FindSupport fSup = FindSupport.getFindSupport(); if (activated) { incSearchTimer.start(); // fSup.incSearch(findPanel.findProps); } else { incSearchTimer.stop(); fSup.incSearchReset(); Utilities.returnFocus(); } } /** Panel that holds the find logic */ public class FindPanel extends FindDialogPanel implements ItemListener, KeyListener, ActionListener { /** * @associates Object */ Map findProps = Collections.synchronizedMap(new HashMap(20)); /** * @associates String */ Map objToProps = Collections.synchronizedMap(new HashMap(20)); FindSupport findSupport = FindSupport.getFindSupport(); static final long serialVersionUID =917425125419841466L; FindPanel() { objToProps.put(findWhat, Settings.FIND_WHAT); objToProps.put(replaceWith, Settings.FIND_REPLACE_WITH); objToProps.put(highlightSearch, Settings.FIND_HIGHLIGHT_SEARCH); objToProps.put(incSearch, Settings.FIND_INC_SEARCH); objToProps.put(matchCase, Settings.FIND_MATCH_CASE); objToProps.put(smartCase, Settings.FIND_SMART_CASE); objToProps.put(wholeWords, Settings.FIND_WHOLE_WORDS); objToProps.put(regExp, Settings.FIND_REG_EXP); objToProps.put(bwdSearch, Settings.FIND_BACKWARD_SEARCH); objToProps.put(wrapSearch, Settings.FIND_WRAP_SEARCH); regExp.setVisible(false); // !!! remove when regexp search is fine String ls = LocaleSupport.getString(Settings.FIND_WHAT); if (ls != null) { findWhatLabel.setText(ls); } ls = LocaleSupport.getString(Settings.FIND_WHAT + MNEMONIC_SUFFIX); char mnemonic = (ls != null && ls.length() > 0) ? ls.charAt(0) : 'n'; findWhatLabel.setLabelFor(findWhat); findWhatLabel.setDisplayedMnemonic(mnemonic); ls = LocaleSupport.getString(Settings.FIND_REPLACE_WITH); if (ls != null) { replaceWithLabel.setText(ls); } ls = LocaleSupport.getString(Settings.FIND_WHAT + MNEMONIC_SUFFIX); mnemonic = (ls != null && ls.length() > 0) ? ls.charAt(0) : 'l'; replaceWithLabel.setLabelFor(replaceWith); replaceWithLabel.setDisplayedMnemonic(mnemonic); ls = LocaleSupport.getString(Settings.FIND_HIGHLIGHT_SEARCH + MNEMONIC_SUFFIX); mnemonic = (ls != null && ls.length() > 0) ? ls.charAt(0) : 'H'; highlightSearch.setMnemonic(mnemonic); ls = LocaleSupport.getString(Settings.FIND_INC_SEARCH + MNEMONIC_SUFFIX); mnemonic = (ls != null && ls.length() > 0) ? ls.charAt(0) : 'I'; incSearch.setMnemonic(mnemonic); ls = LocaleSupport.getString(Settings.FIND_MATCH_CASE + MNEMONIC_SUFFIX); mnemonic = (ls != null && ls.length() > 0) ? ls.charAt(0) : 'C'; matchCase.setMnemonic(mnemonic); ls = LocaleSupport.getString(Settings.FIND_SMART_CASE + MNEMONIC_SUFFIX); mnemonic = (ls != null && ls.length() > 0) ? ls.charAt(0) : 'S'; smartCase.setMnemonic(mnemonic); ls = LocaleSupport.getString(Settings.FIND_WHOLE_WORDS + MNEMONIC_SUFFIX); mnemonic = (ls != null && ls.length() > 0) ? ls.charAt(0) : 'W'; wholeWords.setMnemonic(mnemonic); ls = LocaleSupport.getString(Settings.FIND_REG_EXP + MNEMONIC_SUFFIX); mnemonic = (ls != null && ls.length() > 0) ? ls.charAt(0) : 'E'; regExp.setMnemonic(mnemonic); ls = LocaleSupport.getString(Settings.FIND_BACKWARD_SEARCH + MNEMONIC_SUFFIX); mnemonic = (ls != null && ls.length() > 0) ? ls.charAt(0) : 'B'; bwdSearch.setMnemonic(mnemonic); ls = LocaleSupport.getString(Settings.FIND_WRAP_SEARCH + MNEMONIC_SUFFIX); mnemonic = (ls != null && ls.length() > 0) ? ls.charAt(0) : 'p'; wrapSearch.setMnemonic(mnemonic); load(); findWhat.getEditor().getEditorComponent().addKeyListener(this); findWhat.addActionListener(this); replaceWith.getEditor().getEditorComponent().addKeyListener(this); replaceWith.addActionListener(this); highlightSearch.addItemListener(this); incSearch.addItemListener(this); matchCase.addItemListener(this); smartCase.addItemListener(this); wholeWords.addItemListener(this); regExp.addItemListener(this); bwdSearch.addItemListener(this); wrapSearch.addItemListener(this); } protected Map getFindProps() { return findProps; } void putProperty(Object component, Object value) { String prop = (String)objToProps.get(component); if (prop != null) { findProps.put(prop, value); incSearchTimer.restart(); // findSupport.incSearch(findProps); } } Object getProperty(Object component) { String prop = (String)objToProps.get(component); return (prop != null) ? findProps.get(prop) : null; } boolean getBooleanProperty(Object component) { Object prop = getProperty(component); return (prop != null) ? ((Boolean)prop).booleanValue() : false; } private void changeVisibility(boolean v) { replaceWith.setVisible(v); replaceWithLabel.setVisible(v); getFindButtons()[1].setVisible(v); getFindButtons()[2].setVisible(v); } protected void updateFocus() { SwingUtilities.invokeLater( new Runnable() { public void run() { findWhat.getEditor().getEditorComponent().requestFocus(); findWhat.requestFocus(); findWhat.getEditor().selectAll(); } } ); } protected void updateFind() { changeVisibility(false); } protected void updateReplace() { changeVisibility(true); } private void updateHistory(JComboBox c) { Object item = c.getEditor().getItem(); javax.swing.DefaultComboBoxModel m = new javax.swing.DefaultComboBoxModel(); if (item != null) { m.addElement(item); } int cnt = c.getItemCount(); for (int i = 0; i < cnt; i++) { Object o = c.getItemAt(i); if (o != null && !o.equals(item)) { m.addElement(o); } } c.setModel(m); } protected void updateFindHistory() { updateHistory(findWhat); } protected void updateReplaceHistory() { updateHistory(replaceWith); } protected void updateFindWhat(String selectedText) { findWhat.getEditor().setItem(selectedText); } /** Load the current find properties from those in FindSupport */ void load() { findProps = findSupport.getDefaultFindProperties(); findWhat.getEditor().setItem(getProperty(findWhat)); replaceWith.getEditor().setItem(getProperty(replaceWith)); highlightSearch.setSelected(getBooleanProperty(highlightSearch)); incSearch.setSelected(getBooleanProperty(incSearch)); matchCase.setSelected(getBooleanProperty(matchCase)); smartCase.setSelected(getBooleanProperty(smartCase)); wholeWords.setSelected(getBooleanProperty(wholeWords)); regExp.setSelected(getBooleanProperty(regExp)); bwdSearch.setSelected(getBooleanProperty(bwdSearch)); wrapSearch.setSelected(getBooleanProperty(wrapSearch)); } /** Save the current find properties into those in FindSupport */ void save() { findSupport.putFindProperties(findProps); } void changeFindWhat() { Object old = getProperty(findWhat); Object cur = findWhat.getEditor().getItem(); if (old == null || !old.equals(cur)) { putProperty(findWhat, cur); } } void changeReplaceWith() { Object old = getProperty(replaceWith); Object cur = replaceWith.getEditor().getItem(); if (old == null || !old.equals(cur)) { putProperty(replaceWith, cur); } } private void postChangeCombos() { SwingUtilities.invokeLater( new Runnable() { public void run() { changeFindWhat(); changeReplaceWith(); if (regExp.isSelected()) { } } } ); } public void keyPressed(KeyEvent evt) { postChangeCombos(); } public void keyReleased(KeyEvent evt) { SwingUtilities.invokeLater( new Runnable() { public void run() { changeFindWhat(); changeReplaceWith(); } } ); } public void keyTyped(KeyEvent evt) { if (evt.getKeyChar() == '\n') { FindDialogSupport.this.actionPerformed( new ActionEvent(getFindButtons()[0], 0, null)); } } public void itemStateChanged(ItemEvent evt) { Boolean val = (evt.getStateChange() == ItemEvent.SELECTED) ? Boolean.TRUE : Boolean.FALSE; putProperty(evt.getSource(), val); } public void actionPerformed(ActionEvent evt) { postChangeCombos(); } } } /* * Log * 24 Gandalf-post-FCS1.20.1.2 4/14/00 Miloslav Metelka same replace string * 23 Gandalf-post-FCS1.20.1.1 3/8/00 Miloslav Metelka regexp checkbox * invisible * 22 Gandalf-post-FCS1.20.1.0 3/8/00 Miloslav Metelka * 21 Gandalf 1.20 1/13/00 Miloslav Metelka Localization * 20 Gandalf 1.19 1/7/00 Miloslav Metelka * 19 Gandalf 1.18 1/6/00 Miloslav Metelka * 18 Gandalf 1.17 11/14/99 Miloslav Metelka * 17 Gandalf 1.16 11/8/99 Miloslav Metelka * 16 Gandalf 1.15 10/23/99 Ian Formanek NO SEMANTIC CHANGE - Sun * Microsystems Copyright in File Comment * 15 Gandalf 1.14 10/6/99 Miloslav Metelka * 14 Gandalf 1.13 10/4/99 Miloslav Metelka * 13 Gandalf 1.12 8/27/99 Miloslav Metelka * 12 Gandalf 1.11 8/17/99 Ian Formanek Generated serial version * UID * 11 Gandalf 1.10 8/17/99 Miloslav Metelka * 10 Gandalf 1.9 7/29/99 Miloslav Metelka * 9 Gandalf 1.8 7/26/99 Miloslav Metelka * 8 Gandalf 1.7 7/22/99 Miloslav Metelka * 7 Gandalf 1.6 7/20/99 Miloslav Metelka * 6 Gandalf 1.5 7/2/99 Miloslav Metelka * 5 Gandalf 1.4 6/29/99 Miloslav Metelka Scrolling and patches * 4 Gandalf 1.3 6/1/99 Miloslav Metelka * 3 Gandalf 1.2 5/16/99 Miloslav Metelka * 2 Gandalf 1.1 5/13/99 Miloslav Metelka * 1 Gandalf 1.0 5/5/99 Miloslav Metelka * $ */